﻿<!DOCTYPE html>
<!--[if IE]><![endif]-->
<html>
  
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <title>Web Socket </title>
    <meta name="viewport" content="width=device-width">
    <meta name="title" content="Web Socket ">
    <meta name="generator" content="docfx 2.59.2.0">
    
    <link rel="shortcut icon" href="../../favicon.ico">
    <link rel="stylesheet" href="../../styles/docfx.vendor.css">
    <link rel="stylesheet" href="../../styles/docfx.css">
    <link rel="stylesheet" href="../../styles/main.css">
    <link rel="stylesheet" href="../../styles/socialbar.css">
    <link rel="stylesheet" href="../../styles/header.css">
    <link rel="stylesheet" href="../../styles/version.css">
    <link href="https://fonts.googleapis.com/css?family=Roboto:400,100,300,500,700,100italic,300italic,400italic" rel="stylesheet" type="text/css">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
    <meta property="docfx:navrel" content="../../toc.html">
    <meta property="docfx:tocrel" content="../toc.html">
    <meta property="docfx:uid" content="doc-restapi-Web-Socket">
    
    <meta property="docfx:rel" content="../../">
    
    <script type="text/javascript" src="../../nav.js"></script>
    <script type="text/javascript" src="../toc.js"></script>
  
  </head>  <body data-spy="scroll" data-target="#affix" data-offset="120">
    <div id="wrapper">
      <header>
        
        <div class="mb-socials-heading" style="height: 40px;">
        	<div class="mb-socials-heading-inner container">
        		<div class="mb-socials-heading-right">
        			<div class="mb-socials-list">
                          
        				<div class="mb-socials-item facebook">
        					<a class="mb-socials-item-link" target="_blank" href="https://facebook.com/embyapp"></a>
        					<div class="mb-socials-item-popup">
        						<span>Facebook</span>
        					</div>
        				</div><div class="mb-socials-item twitter">
        					<a class="mb-socials-item-link" target="_blank" href="https://twitter.com/embyapp"></a>
        					<div class="mb-socials-item-popup">
        						<span>Twitter</span>
        					</div>
        				</div>
        				<div class="mb-socials-item pinterest">
        					<a class="mb-socials-item-link" target="_blank" href="https://www.pinterest.com/emby0240/emby-news/"></a>
        					<div class="mb-socials-item-popup">
        						<span>Pinterest</span>
        					</div>
        				</div>
        				<div class="mb-socials-item tumblr">
        					<a class="mb-socials-item-link" target="_blank" href="https://embyapp.tumblr.com/"></a>
        					<div class="mb-socials-item-popup">
        						<span>Tumblr</span>
        					</div>
        				</div>
        				<div class="mb-socials-item github">
        					<a class="mb-socials-item-link" target="_blank" href="https://github.com/MediaBrowser"></a>
        					<div class="mb-socials-item-popup">
        						<span>GitHub</span>
        					</div>
        				</div><div class="mb-socials-item rss">
        					<a class="mb-socials-item-link" target="_blank" href="https://emby.media/blog.xml"></a>
        					<div class="mb-socials-item-popup">
        						<span>RSS</span>
        					</div>
        				</div>
                          
        			</div>
        		</div>
        	</div>
        </div>
        <div class="container">
        	<nav id="autocollapse" class="navbar navbar-inverse ng-scope" role="navigation">
        		  
        		  <a class="navbar-brand" href="../../index.html">
        		    <img id="logo" class="svg" src="../../images/emby_dev_logo.png" alt="">
        		  </a>
        		  <button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#navbar">
        			<span class="sr-only">Toggle navigation</span>
        			<span class="icon-bar"></span>
        			<span class="icon-bar"></span>
        			<span class="icon-bar"></span>
        		  </button>
        		<div class="collapse navbar-collapse" id="navbar">
        			
        			<ul class="nav level1 navbar-nav">
        			      <li class="nav-item">
        			          <a class="nav-link" href="../../index.html" title="DEV Home">DEV Home</a>
        			      </li>
        			      <li class="nav-item">
        			          <a class="nav-link" href="../../doc/index.html" title="Documentation">Documentation</a>
        			      </li>
        			      <li class="nav-item">
        			          <a class="nav-link" href="../../reference/index.html" title="Reference">Reference</a>
        			      </li>
        			      <li class="nav-item">
        			          <a class="nav-link" href="../../download/index.html" title="Download">Download</a>
        			      </li>
        			</ul>		</div>
        	</nav>
        </div>
        <div class="nav-overlay d-none"></div>        
        <div class="subnav navbar navbar-default">
          <div class="container">
            <div class="hide-when-search" id="breadcrumb">
        	  <ul class="breadcrumb">
        		<li></li>
        	  </ul>
        	</div>
        
        	<div class="breadcrumpsearch">
        	  <form class="navbar-form navbar-right" role="search" id="search">
        		<div class="form-group">
        		  <input type="text" class="form-control" id="search-query" placeholder="Search" autocomplete="off">
        		</div>
        	  </form>
        	</div>
          </div>
        </div>
      </header>
      <div class="container body-content">
        
        <div id="search-results">
          <div class="search-list">Search Results for <span></span></div>
          <div class="sr-items">
            <p><i class="glyphicon glyphicon-refresh index-loading"></i></p>
          </div>
          <ul id="pagination" data-first="First" data-prev="Previous" data-next="Next" data-last="Last"></ul>
        </div>
      </div>
      <div role="main" class="container body-content hide-when-search">
        
        <div class="sidenav hide-when-search">
          <a class="btn toc-toggle collapse" data-toggle="collapse" href="#sidetoggle" aria-expanded="false" aria-controls="sidetoggle">Show / Hide Table of Contents</a>
          <div class="sidetoggle collapse" id="sidetoggle">
            <div id="sidetoc"></div>
          </div>
        </div>
        <div class="article row grid-right">
          <div class="col-md-10">
            <article class="content wrap" id="_content" data-uid="doc-restapi-Web-Socket">
<h1 id="web-socket">Web Socket</h1>

<p>Clients are recommended to connect to the server's web socket in order to receive notifications of various system events, which can help reduce the need to repeatedly poll for data through the http api.</p>
<p>The web socket is also the preferred protocol from which to receive remote control commands.</p>
<h3 id="connecting-to-the-web-socket">Connecting to the web socket</h3>
<p>Once connected to the server, simply take the server's http address, and change the protocol to ws:// or wss://.</p>
<pre><code>ws://{host}?api_key={authenticationtoken}&amp;deviceId={deviceId}
</code></pre>
<p>To construct the url, perform a string replacement on the http url rather than building it manually. This will allow your app to support addresses without ports, as well as http/https.</p>
<p>Replace the following:</p>
<p>http: -&gt; ws:</p>
<p>https: -&gt; wss:</p>
<h3 id="message-format">Message format</h3>
<p>All messages sent and received over the web socket are in the format of a json structure:</p>
<pre><code class="lang-json">{
    MessageType: &quot;RestartRequired&quot;,
    Data: &quot;&quot;
}
</code></pre>
<p>MessageType is the name of the event or action, Data is any related data. Data can be plain text, or a json structure itself, depending on MessageType.</p>
<h2 id="messages">Messages</h2>
<p>Once connected and identified, you'll be able to receive the following MessageTypes from the web socket:</p>
<h4 id="generalcommand">GeneralCommand</h4>
<p>See below section on commands.</p>
<h4 id="userdatachanged">UserDataChanged</h4>
<p>A user changed their personal rating for an item, or their playstate was updated. Data = a json object with the following properties:</p>
<ul>
<li>UserId</li>
<li>UserDataList - a list of updated user data objects</li>
</ul>
<h4 id="userdeleted">UserDeleted</h4>
<p>Data = the user id that has been deleted</p>
<h4 id="userupdated">UserUpdated</h4>
<p>Data = the user object that has been updated</p>
<h4 id="notificationadded">NotificationAdded</h4>
<p>A user has new notifications. Presentations should refresh their notification list.</p>
<h4 id="notificationsmarkedread">NotificationsMarkedRead</h4>
<p>A user has marked notifications read. Presentations should refresh their notification list.</p>
<h4 id="restartrequired">RestartRequired</h4>
<p>This indicates the server needs to be restarted. There is no data associated with this.</p>
<h4 id="serverrestarting-servershuttingdown">ServerRestarting, ServerShuttingDown</h4>
<p>This will tell you when the server is restarting or shutting down.</p>
<h4 id="play">Play</h4>
<p>A remote control play command has been sent from the server. Data = a json object with the following properties:</p>
<ul>
<li>ItemIds - an array of item id's to play</li>
<li>PlayCommand - PlayNow, PlayNext or PlayLast</li>
<li>StartPositionTicks - If supplied, this is the position in which the first title should start at.</li>
<li>MediaSourceId - If supplied, this is the media source that should be used for the first item</li>
<li>AudioStreamIndex - If supplied, this is the audio stream that should be used for the first item</li>
<li>SubtitleStreamIndex - If supplied, this is the subtitle stream that should be used for the first item</li>
<li>StartIndex - If supplied, and if playing a list of items, this is the index of the first item that should be played.</li>
</ul>
<h4 id="playstate">Playstate</h4>
<p>A remote control update playstate command has been sent from the server. Data = a json object with the following properties:</p>
<ul>
<li>Command - Stop, Pause, Unpause, NextTrack, PreviousTrack, Seek</li>
<li>SeekPositionTicks - Used with the seek command.</li>
</ul>
<h2 id="general-commands">General Commands</h2>
<p>Most remote control commands are implemented in a pass-through fashion. That is the server simply takes the command and passes it directly to the client without modification.</p>
<p>The standard web socket message format is utilized. The Data property is an object describing the remote control command. The command will have two properties:</p>
<ul>
<li>Name</li>
<li>Arguments.</li>
</ul>
<p>Below are the list of known core command <strong>names</strong>, along with the list of properties available in Arguments.</p>
<ul>
<li>MoveUp,</li>
<li>MoveDown,</li>
<li>MoveLeft,</li>
<li>MoveRight,</li>
<li>PageUp,</li>
<li>PageDown,</li>
<li>PreviousLetter (scroll list to previous letter),</li>
<li>NextLetter (scroll list to next letter),</li>
<li>ToggleOsd  (show or hide video player OSD),</li>
<li>ToggleContextMenu (show or hide information relating to selected list item),</li>
<li>Select (enter),</li>
<li>Back,</li>
<li>TakeScreenshot,</li>
<li>SendKey (tbd),</li>
<li>SendString (Enter text into application - Arguments: String),</li>
<li>GoHome,</li>
<li>GoToSettings,</li>
<li>VolumeUp,</li>
<li>VolumeDown,</li>
<li>Mute,</li>
<li>Unmute,</li>
<li>ToggleMute,</li>
<li>SetVolume (Arguments: Volume 0-100 scale),</li>
<li>SetAudioStreamIndex = (Arguments: Index),</li>
<li>SetSubtitleStreamIndex = (Arguments: Index. If -1 turn off subtitles),</li>
<li>ToggleFullscreen ,</li>
<li>DisplayContent (Arguments: ItemName, ItemId, ItemType),</li>
<li>GoToSearch,</li>
<li>DisplayMessage (Arguments: Header, Text, TimeoutMs - if timeout is omitted, message should be modal)</li>
<li>PlayTrailers (Arguments: ItemId),</li>
<li>PlayMediaSource - used to indicate support for receiving the play command along with a specified MediaSourceId, AudioStreamIndex and SubtitleStreamIndex</li>
<li>SetPlaybackRate (Arguments: PlaybackRate - floating point playback rate value)</li>
<li>SetSubtitleOffset (Arguments: SubtitleOffset - floating point subtitle offset value)</li>
<li>IncrementSubtitleOffset (Arguments: Increment - floating point subtitle offset increment value)</li>
</ul>
<h2 id="examples">Examples</h2>
<p>Sample code that parses web server messages can be found here:</p>
<p><a href="https://github.com/MediaBrowser/Emby.ApiClient/blob/master/MediaBrowser.ApiInteraction/ApiWebSocket.cs#L399">https://github.com/MediaBrowser/Emby.ApiClient/blob/master/MediaBrowser.ApiInteraction/ApiWebSocket.cs#L399</a></p>
</article>
          </div>
          
          <div class="hidden-sm col-md-2" role="complementary">
            <div class="sideaffix">
              <div class="contribution">
                <ul class="nav">
                </ul>
              </div>
              <div class="sdkversion Release">
                  SDK <span class="sdkVersionSpan"></span>
              </div>
              <nav class="bs-docs-sidebar hidden-print hidden-xs hidden-sm affix" id="affix">
                <h5>On this Page</h5>
                <div></div>
              </nav>
            </div>
          </div>
        </div>
      </div>
      
      <footer>
        <div class="grad-bottom"></div>
        <div class="footer">
          <div class="container">
            <span class="pull-right">
              <a href="#top">Back to Top</a>
            </span>
            Copyright 2022 © EMBY LLC.  Please see our <a class="lnk" href="https://emby.media/terms.html">terms of use</a> and <a class="lnk" href="https://emby.media/privacy.html">privacy policy</a>.
            
          </div>
        </div>
      </footer>
    </div>
    
    <script type="text/javascript" src="../../styles/docfx.vendor.js"></script>
    <script type="text/javascript" src="../../searchIndex.js"></script>
    <script type="text/javascript" src="../../styles/lunr.min.js"></script>
    <script type="text/javascript" src="../../styles/docfx.js"></script>
    <script type="text/javascript" src="../../styles/main.js"></script>
  </body>
</html>
